package com.huike.clues.service.impl;

import com.huike.clues.service.ISysFileService;
import com.huike.common.config.MinioConfig;
import com.huike.common.core.domain.AjaxResult;
import com.huike.common.utils.uuid.UUID;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

@Service
@Slf4j
public class SysFileServiceImpl implements ISysFileService {

    @Autowired
    MinioConfig minioConfig;

    /**
     * 文件上传至Minio
     * 使用try catch finally进行上传
     * finally里进行资源的回收
     */
    @Override
    public AjaxResult upload(MultipartFile file) {
        InputStream inputStream = null;

        MinioClient minioClient = getClient();//创建Minio的连接对象
        String bucketName = minioConfig.getBucketName(); //获取桶名

        try {
            inputStream = file.getInputStream();
            /**
             * 思路：我们上传的文件是:合同.pdf
             * 那么我们应该上传到配置的bucket内 我们配置的bucketName是huike-crm
             * 并且放在huike-crm/2021/05/05/这个目录下
             * 而对于同一个文件，存在重名问题，所以我们应该利用UUID生成一个新的文件名，并拼接上 .pdf 作为文件后缀
             * 那么完整的路径就是 huike-crm/2021/05/05/uuid.pdf
             */
            //TODO 基于上述逻辑补全代码
            //1. 文件名处理
            String fileName = file.getOriginalFilename();//获取参数的文件名
           String objectName = new SimpleDateFormat("yyyy/MM/dd/").format(new Date())+
                    UUID.randomUUID().toString().replaceAll("-","")
                    + fileName.substring(fileName.lastIndexOf("."));
            //2. 文件上传
            PutObjectArgs objectArgs = PutObjectArgs.builder()
                    .object(objectName)//文件名
                    .bucket(bucketName)//桶名
                    .contentType(file.getContentType())//文件名
                    //参数1:文件流  参数2:文件大小 参数3:分片大小
                    .stream(file.getInputStream(), file.getSize(), -1).build();//流

            minioClient.putObject(objectArgs);//使用minio的连接对象调用上传方法
            //3. 构建返回结果集,将文件名(fileName)和访问路径(url)返回
            AjaxResult ajax = AjaxResult.success();
            // "fileName":"/profile/huike-crm/2022/03/18/8916214c-44ff-4aef-83bb-dbc7d3f88ed8.pdf"
            ajax.put("fileName","/"+bucketName+"/"+objectName);//要和接口要求一致,桶名+加密的文件名称
            //"url":"http://127.0.0.1:9000/huike-crm/2022/03/18/8916214c-44ff-4aef-83bb-dbc7d3f88ed8.pdf"
            ajax.put("url","http://"+minioConfig.getEndpoint()+":"+minioConfig.getPort()+"/"+
                    minioConfig.getBucketName()+"/"+objectName);

            //4. 将结果返回
            return ajax;
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("上传失败");
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close(); // 关闭流
                } catch (IOException e) {
                    log.debug("inputStream close IOException:" + e.getMessage());
                }
            }
        }
    }


    /**
     * 免费提供一个获取Minio连接的方法
     * 获取Minio连接
     *
     * @return
     */
    private MinioClient getClient() {
        MinioClient minioClient =
                MinioClient.builder()
                        .endpoint("http://" + minioConfig.getEndpoint() + ":" + minioConfig.getPort())
                        .credentials(minioConfig.getAccessKey(), minioConfig.getSecretKey())
                        .build();
        return minioClient;
    }
}
